﻿using System;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace SHomeWorkshop.LunarMind.Adorners
{
    public class TitleSelectedAdorner : Adorner
    {
        // Be sure to call the base class constructor.
        /// <summary>
        /// 用以表示标题被选取状态的装饰器。
        /// </summary>
        /// <param name="adornedElement">应传入标题的“MainBorder”主子元素。</param>
        public TitleSelectedAdorner(UIElement adornedElement, Title masterTitle)
            : base(adornedElement)
        {
            this.masterTitle = masterTitle;

            //终于解决了选取装饰器中线条宽度为2而不是1像素的问题！！！
            this.SnapsToDevicePixels = true;
            this.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);

            this.MouseLeave += TitleSelectedAdorner_MouseLeave;
        }

        void TitleSelectedAdorner_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.InvalidateVisual();
        }

        private Title masterTitle;

        public Title MasterTitle
        {
            get { return masterTitle; }
        }

        // A common way to implement an adorner's rendering behavior is to override the OnRender
        // method, which is called by the layout system as part of a rendering pass.
        protected override void OnRender(DrawingContext drawingContext)
        {
            if (this.Visibility != System.Windows.Visibility.Visible || masterTitle == null) return;

            Brush baseBrush = LunarConcept.Tools.BrushManager.SevenColors;
            //if (this.masterTitle.CommentTextBlock.Text.Length > 0)
            //{
            //    baseBrush = Brushes.Green;
            //}
            //else
            //{
            //    baseBrush = Brushes.Blue;
            //}

            Rect adornedElementRect = new Rect(this.AdornedElement.RenderSize);

            adornedElementRect = FormatRect(adornedElementRect);

            Pen linePen = null;

            if (masterTitle.IsSelected == false) return;

            #region 废弃了上下画两个小三角的做法，不再使用装饰器来实现提醒鼠标位置的功能。改用动画实现。
            //{
            //    if (this.IsMouseOver || masterTitle.IsMouseOver)
            //    {
            //        linePen = new Pen(Brushes.MediumVioletRed, 1);
            //        drawingContext.DrawRectangle(null, linePen, adornedElementRect);
            //        //否则拖不出备注框了，因为载断了事件。

            //        Point center = new Point(adornedElementRect.X + adornedElementRect.Width / 2, adornedElementRect.Y + adornedElementRect.Height / 2);

            //        //上下各画一个小三角

            //        PathGeometry geometry = new PathGeometry();
            //        PathFigure figureTop = new PathFigure()
            //        {
            //            StartPoint = new Point(center.X, adornedElementRect.Top - 4),
            //            IsClosed = true,
            //            IsFilled = true,
            //        };

            //        PathFigure figureBottom = new PathFigure()
            //        {
            //            StartPoint = new Point(center.X, adornedElementRect.Bottom + 4),
            //            IsClosed = true,
            //            IsFilled = true,
            //        };
            //        geometry.Figures.Add(figureTop);
            //        geometry.Figures.Add(figureBottom);

            //        double l = Math.Min(adornedElementRect.Width, adornedElementRect.Height) / 4;

            //        figureTop.Segments.Add(new PolyLineSegment()
            //        {
            //            Points ={
            //                new Point(figureTop.StartPoint.X-l,figureTop.StartPoint.Y-l),
            //                new Point(figureTop.StartPoint.X+l,figureTop.StartPoint.Y-l),
            //                }
            //        });

            //        figureBottom.Segments.Add(new PolyLineSegment()
            //        {
            //            Points ={
            //                new Point(figureBottom.StartPoint.X-l,figureBottom.StartPoint.Y+l),
            //                new Point(figureBottom.StartPoint.X+l,figureBottom.StartPoint.Y+l),
            //                }
            //        });

            //        drawingContext.DrawGeometry(Brushes.MediumVioletRed, linePen, geometry);
            //    }

            //    return;
            //} 
            #endregion


            Pen markPen50 = new Pen(baseBrush, 1);
            Pen markPen100 = new Pen(baseBrush, 1);

            #region 先画线。

            Point newTopLeft = new Point(adornedElementRect.TopLeft.X - 2, adornedElementRect.TopLeft.Y - 2);
            Point ptTmp = new Point(adornedElementRect.BottomRight.X + 2, adornedElementRect.BottomRight.Y + 2);
            Rect lineRect = new Rect(newTopLeft, ptTmp);

            if (this.masterTitle.Editor != null)
            {
                linePen = new Pen(baseBrush, 1);
                //linePen = this.masterTitle.Editor.SubPanelSelectionAdornerPen;
                //linePen.DashStyle = DashStyles.DashDot;


                linePen.LineJoin = PenLineJoin.Round;
                linePen.StartLineCap = PenLineCap.Round;
                linePen.EndLineCap = PenLineCap.Round;


                //使用这个办法其实比画四条线更好。但要注意，第一个参数必须为：null而不能是：Brshes.Transparent。
                //否则画出来的矩形不是空心的。
                //由于公式需要嵌套，一旦矩形不是空心，则选中外层的公式后，
                //就不能再用鼠标选中内层的公式了。
                drawingContext.DrawRectangle(null, linePen, lineRect);
            }

            Rect outLineRect = new Rect(adornedElementRect.Left - 2, adornedElementRect.Top - 5, adornedElementRect.Width + 5, adornedElementRect.Height + 10);
            drawingContext.DrawRectangle(null, markPen100, outLineRect);

            #endregion

            #region 再画点。
            //SolidColorBrush renderBrush;
            Brush renderBrush;
            Pen renderPen;
            Brush squareBrush;

            if (this.masterTitle != null && this.masterTitle.Editor != null)
            {
                renderPen = new Pen(baseBrush, 1);
                //renderPen = this.masterTitle.Editor.ExSelectionAdornerPen;

                if (masterTitle.IsMainSelectedTitle)
                {
                    renderBrush = baseBrush;
                    squareBrush = baseBrush;
                }
                else
                {
                    renderBrush = Brushes.White;
                    squareBrush = Brushes.Transparent;
                }
                //renderBrush = this.masterTitle.Editor.ExSelectionAdornerBrush;
            }
            else
            {
                renderPen = null;
                renderBrush = null;
                squareBrush = baseBrush;
            }


            drawingContext.DrawRectangle(renderBrush/*Brushes.Black*/, renderPen,
                new Rect(adornedElementRect.Left - 5, adornedElementRect.Top - 5, 3, adornedElementRect.Height + 10));//左


            drawingContext.DrawRectangle(renderBrush/*Brushes.Black*/, renderPen,
                new Rect(adornedElementRect.Right + 2, adornedElementRect.Top - 5, 3, adornedElementRect.Height + 10));//右

            //drawingContext.DrawRectangle(renderBrush/*Brushes.Black*/, renderPen,
            //    new Rect(adornedElementRect.Left - 4, adornedElementRect.Top - 4, 4, 4));//左上
            //drawingContext.DrawRectangle(renderBrush/*Brushes.Black*/, renderPen,
            //    new Rect(adornedElementRect.Right + 1, adornedElementRect.Top - 4, 4, 4));//右上
            //drawingContext.DrawRectangle(renderBrush/*Brushes.Black*/, renderPen,
            //    new Rect(adornedElementRect.Left - 4, adornedElementRect.Bottom + 1, 4, 4));//左下
            //drawingContext.DrawRectangle(renderBrush/*Brushes.Black*/, renderPen,
            //    new Rect(adornedElementRect.Right + 1, adornedElementRect.Bottom + 1, 4, 4));//右下

            #endregion

            #region 最后再画些纵线，以便判断标题的宽度

            double leftBase = adornedElementRect.Left - 2;
            double bottomBase = adornedElementRect.Bottom + 2;
            double topBase = adornedElementRect.Top - 2;
            double rightBase = adornedElementRect.Right + 2;

            for (int i = 50; i < rightBase; i += 50)//不从零开始更好，可以避免末尾一个多余。
            {
                if (i % 100 == 0)
                {
                    Point pt1 = new Point(leftBase + i, bottomBase);
                    Point pt2 = new Point(pt1.X, pt1.Y + 3);
                    drawingContext.DrawLine(markPen100, pt1, pt2);

                    pt1 = new Point(leftBase + i, topBase - 3);
                    pt2 = new Point(pt1.X, pt1.Y + 3);
                    drawingContext.DrawLine(markPen100, pt1, pt2);

                }
                else
                {
                    Point pt1 = new Point(leftBase + i, bottomBase);
                    Point pt2 = new Point(pt1.X, pt1.Y + 3);
                    drawingContext.DrawLine(markPen50, pt1, pt2);

                    pt1 = new Point(leftBase + i, topBase - 3);
                    pt2 = new Point(pt1.X, pt1.Y + 3);
                    drawingContext.DrawLine(markPen50, pt1, pt2);
                }
            }

            for (int i = 100; i <= rightBase + 100; i += 100)//不从零开始更好，可以避免末尾一个多余。
            {
                Point pt1 = new Point(leftBase + i, topBase - 3);
                Point pt2 = new Point(pt1.X, pt1.Y + 2);

                var pt11 = new Point(pt1.X - 50, pt1.Y);
                var pt12 = new Point(pt1.X, pt1.Y + 1);

                if (pt12.X > rightBase) pt12.X = rightBase;

                if (pt12.X > pt11.X)
                {
                    drawingContext.DrawRectangle(squareBrush, renderPen, new Rect(pt11.X, outLineRect.Top, pt12.X - pt11.X, 3));
                }

                if (i % 200 == 0)
                {
                    var pt21 = new Point(pt2.X - 100, bottomBase + 3);
                    var pt22 = new Point(pt2.X, bottomBase + 3);

                    if (pt22.X > rightBase) pt22.X = rightBase;

                    if (pt22.X > pt21.X)
                    {
                        drawingContext.DrawRectangle(squareBrush, renderPen, new Rect(pt21.X, lineRect.Bottom, pt22.X - pt21.X, 3));
                    }
                }
            }

            #endregion
        }

        private Rect FormatRect(Rect rect)
        {
            rect.X = (int)rect.X;
            rect.Y = (int)rect.Y;
            rect.Width = (int)rect.Width + 1;
            rect.Height = (int)rect.Height + 1;

            return rect;
        }
    }
}
